package models.weixin.auth;


import helper.GlobalConfig;
import me.chanjar.weixin.common.bean.WxJsapiSignature;
import me.chanjar.weixin.common.exception.WxErrorException;
import me.chanjar.weixin.mp.api.WxMpConfigStorage;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.bean.result.WxMpOAuth2AccessToken;
import me.chanjar.weixin.mp.bean.result.WxMpUser;
import models.weixin.WebUser;
import models.weixin.WeixinData;
import models.weixin.WxMpHelper;
import org.apache.commons.lang.StringUtils;
import play.Logger;
import play.Play;
import play.mvc.Before;
import play.mvc.Controller;

import java.util.Arrays;
import java.util.List;

/**
 * 微信公众号认证，基于OAuth.
 */
public class WxMpAuthSaleMan extends Controller {

    private final static ThreadLocal<WebUser> _currentUser = new ThreadLocal<>();

    @Before
    public static void filter() throws Throwable {

        // 不存在
        String ua = "";
        //通过request 获取浏览器的某些参数
        if (request.headers.get("user-agent") != null) {
            ua = request.headers.get("user-agent").toString().toLowerCase();
        }

        // 判断是否为微信浏览器
        if (ua.indexOf("micromessenger") > 0) {
            // 正式环境运行
            if (Play.mode.isProd()) {

                //如果用户不存在 从微信端获取微信用户信息
                // 写到Global
                WeixinData weixinData = WeixinData.findById(GlobalConfig.WEIXIN_DATA_ID);

                // 调用微信 或者 第三方 微信方法。 得到获取微信用户的基本参数
                WxMpConfigStorage wxMpConfigStorage = WxMpHelper.getWxMpConfigStorage(weixinData);
                if (wxMpConfigStorage == null) {
                    renderText("不存在的应用地址，请检查域名是否正确.");
                    return;
                }
                WxMpService wxMpService = WxMpHelper.getWxMpService(wxMpConfigStorage);


                // 设置JSAPI
                UseJsApi annoUseJsAPI = getUseJsAPI();
                if (annoUseJsAPI != null) {
//                    Logger.info("获取到的 代理的linkId : %s", linkId);
                    String jsapiTicket = wxMpService.getJsapiTicket(false);
                    String currentUrl = "http://" + request.host + request.url;
                    WxJsapiSignature jsSignature = null;
                    try {
                        jsSignature = wxMpService.createJsapiSignature(currentUrl);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
//                    Logger.info("url=" + currentUrl + ", jsapiTicket=" + jsapiTicket);
                    Logger.info("获取jsSignature 需要的参数值： jsapiTicket :%s",jsapiTicket);
                    Logger.info("获取jsSignature 需要的参数值： currentUrl :%s",currentUrl);
                    List<String> jsApis = Arrays.asList(annoUseJsAPI.value());
                    Logger.info("-微信接口相关参数----------jsSignature:%s | jsApis :%s  | jsAppId :%s" , jsSignature ,jsApis , wxMpConfigStorage.getAppId());
                    renderArgs.put("jsSignature", jsSignature);
                    renderArgs.put("jsApis", jsApis);
                    renderArgs.put("jsAppId", wxMpConfigStorage.getAppId());
                }
                if (skipAuthCheck()) {
                    Logger.info("[Auth]: Skip the Auth Check.");
                    return;
                }

                //如果用户存在 直接过滤掉
                WebUser webUser = getUserFromSession();
                // 存在
                if (webUser != null) {
                    _currentUser.set(webUser);
                    renderArgs.put("webUser", webUser);
                    return;
                }


                // 通过 wxMpService 获取 访问者用户的微信信息。
                // 72000秒以内。 我可以授权给你一个编码， 让你可以通过这个编码来获取微信用户信息。 不用每次都调用方法过来请求。
                String code = params.get("code");
                String state = params.get("state");
                // code 为空。 得去微信那边获取。  如果code 存在。 用code 获取信息。
                Logger.info("Code : %s | state : %s", code, state);
                if (StringUtils.isBlank(code) || StringUtils.isBlank(state)) {
                    // http://ulcweixin.ulmsale.net/1?code=1123812389123123
                    String targetUrl = "http://" + request.host + request.url;
                    Logger.info("targetUrl : %s", targetUrl);
                    String randomState = util.common.RandomNumberUtil.generateRandomChars(12);  // 考虑一下UUI
                    String redirectUrl = wxMpService.oauth2buildAuthorizationUrl(targetUrl, "snsapi_userinfo", randomState);
                    redirect(redirectUrl);
                } else {
                    // 通过 code 获取 WebUser
                    WxMpOAuth2AccessToken wxMpOAuth2AccessToken = null;
                    try {
                        wxMpOAuth2AccessToken = wxMpService.oauth2getAccessToken(code);
                        //从微信那里获取到的当前的微信用户的信息
                        WxMpUser wxMpUser = wxMpService.oauth2getUserInfo(wxMpOAuth2AccessToken, "zh_CN");
                        //
//                        WebUser currentUser = WxMpHelper.getUserFromOpenId(wxMpUser.getOpenId());
                        Logger.info("----------------微信获取到的 wxMpUser :%s" , wxMpUser);


                        String identityCode =  session.get(GlobalConfig.WEIXIN_WEB_USER_IDENTITY_CODE)  ;
                        //如果授权码为空跳转至登录页面
                        if(StringUtils.isBlank(identityCode))
                            redirect("/login");


                        webUser = WebUser.findByIdentityCode(identityCode);
                        Logger.info("----------------通过授权码获取到的 webUser :%s" , webUser);



                        if(webUser == null){
                            session.remove(GlobalConfig.WEIXIN_WEB_USER_IDENTITY_CODE);
                            session.remove(GlobalConfig.WEIXIN_MP_WEIXIN_SESSION_USER_ID);
                            flash.put("msg","该授权码无对应的用户，请输入正确的授权码 ~ ");
                            redirect("/login");
                        }
//                        if(webUser == null){
//                            //强行删掉缓存
//                            session.remove(GlobalConfig.WEIXIN_MP_WEIXIN_SESSION_USER_ID);
//                            renderText("您还不是我们的用户，无法进入.");
//                            return;
//                        }
//
//                        GiveWebUserAuth saleMan = GiveWebUserAuth.findByWebuser(webUser.id);
//                        if (saleMan == null) {
//                            session.remove(GlobalConfig.WEIXIN_MP_WEIXIN_SESSION_USER_ID);
//                            renderText("您不是业务人员，无法进入！");
//                            return;
//                        }

                        session.put(GlobalConfig.WEIXIN_WEB_USER_IDENTITY_CODE, identityCode);
                        session.put(GlobalConfig.WEIXIN_MP_WEIXIN_SESSION_USER_ID, webUser.id);
                        _currentUser.set(webUser);
                        renderArgs.put("webUser", webUser);

                    } catch (WxErrorException e) {
                        e.printStackTrace();
                    }

                }


            } else { //测试开发环境

                String identityCode =  session.get(GlobalConfig.WEIXIN_WEB_USER_IDENTITY_CODE) ;
                //如果授权码为空跳转至登录页面
                if(StringUtils.isBlank(identityCode))
                    redirect("/login");

                WebUser webUser = WebUser.findByIdentityCode(identityCode);
                Logger.info("----------------通过授权码获取到的 webUser :%s" , webUser);

                if(webUser == null){
                    session.remove(GlobalConfig.WEIXIN_MP_WEIXIN_SESSION_USER_ID);
                    session.remove(GlobalConfig.WEIXIN_WEB_USER_IDENTITY_CODE);
                    flash.put("msg","该授权码无对应的用户，请输入正确的授权码 ~ ");
                    redirect("/login");
                }
//                WebUser webUser = WebUser.findByUserId(5717l);
                session.put(GlobalConfig.WEIXIN_WEB_USER_IDENTITY_CODE , identityCode);
                session.put(GlobalConfig.WEIXIN_MP_WEIXIN_SESSION_USER_ID , webUser.id);
                _currentUser.set(webUser);
                renderArgs.put("webUser" , webUser);
//                GiveWebUserAuth saleMan = GiveWebUserAuth.findByWebuser(webUser.id);
//                if (saleMan == null) {
//                    //强行删掉缓存
//                    session.remove(GlobalConfig.WEIXIN_MP_WEIXIN_SESSION_USER_ID);
//                    renderText("您不是业务员，无法进入！");
//                    return;
//                }
//                return;
            }
        } else {
            redirect("/error/blank");
//            renderText("请用微信打开！");

        }


    }

    /**
     * 尝试从Session中得到用户信息.
     */
    private static WebUser getUserFromSession() {

        WebUser webUser = null;

        String userId = session.get(GlobalConfig.WEIXIN_MP_WEIXIN_SESSION_USER_ID);
        Logger.info("Session.userId : %s", userId);
        if (StringUtils.isNotBlank(userId)) {
            webUser = WebUser.findById(Long.valueOf(userId));
            return webUser;
        }
        return webUser;
    }

    /**
     * 在Controller中使用WexinCpAuth可以得到当前用户.
     */
    public static WebUser currentUser() {
        return _currentUser.get();
    }

    /**
     * 检查是否要跳过认证检查.
     *
     * @return 返回true表明跳过检查.
     */
    private static boolean skipAuthCheck() {
        if (getActionAnnotation(SkipAuth.class) != null ||
                getControllerInheritedAnnotation(SkipAuth.class) != null) {
            Logger.info("skipAuthCheck=true");
            return true;
        }
        Logger.info("skipAuthCheck=false");
        return false;
    }

    /**
     * 检查是否要使用JSAPI.
     * <p>
     * 在类名或方法上使用@UseJsAPI标注，会在renderArgs中加入一个jsSignature的对象.
     *
     * @return UseJsAPI，其value指定需要的权限.
     */
    private static UseJsApi getUseJsAPI() {
        if (getActionAnnotation(UseJsApi.class) != null) {
            Logger.info("UseJsAPI on Action");
            return getActionAnnotation(UseJsApi.class);
        }
        if (getControllerInheritedAnnotation(UseJsApi.class) != null) {
            Logger.info("UseJsAPI on Controller");
            return getControllerInheritedAnnotation(UseJsApi.class);
        }
        Logger.info("UseJsAPI=false");
        return null;
    }


}
